package com.tarena.lbs.common.utils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 列表匹配工具类：判断两个列表是否存在至少一个共同元素
 */
public class ListMatchUtils {

    /**
     * 核心方法：判断两个列表是否存在交集（有一个元素匹配则返回true）
     * @param list1 第一个列表（支持任意引用类型，如Integer、String、自定义对象等）
     * @param list2 第二个列表（同list1类型）
     * @param <T> 列表元素类型（需确保元素重写了equals()和hashCode()，否则自定义对象可能匹配失效）
     * @return true：存在至少一个匹配元素；false：无匹配元素或任一列表为空/Null
     */
    public static <T> boolean hasAnyMatch(List<T> list1, List<T> list2) {
        // 1. 空值防御：任一列表为Null或空，直接返回false（无元素可匹配）
        if (list1 == null || list1.isEmpty() || list2 == null || list2.isEmpty()) {
            return false;
        }

        // 2. 性能优化：将「较小的列表」转为Set（减少Set内存占用+缩短转换时间）
        // Set的contains()是O(1)哈希查找，比List的O(n)遍历快10倍以上（大列表场景更明显）
        Set<T> elementSet = list1.size() <= list2.size()
                ? list1.stream().collect(Collectors.toSet())
                : list2.stream().collect(Collectors.toSet());

        // 3. 遍历「较大的列表」，检查是否有元素在Set中（找到匹配立即返回，减少循环次数）
        List<T> targetList = list1.size() > list2.size() ? list1 : list2;
        for (T element : targetList) {
            if (elementSet.contains(element)) {
                return true; // 找到匹配元素，立即返回（无需遍历剩余元素）
            }
        }

        // 4. 遍历结束无匹配
        return false;
    }


    // ------------------------------ 测试示例 ------------------------------
    public static void main(String[] args) {
        // 测试1：Integer类型列表（有匹配）
        List<Integer> intList1 = List.of(1, 2, 3, 4);
        List<Integer> intList2 = List.of(5, 6, 3);
        System.out.println("Integer列表匹配结果：" + hasAnyMatch(intList1, intList2)); // true（3匹配）

        // 测试2：String类型列表（无匹配）
        List<String> strList1 = List.of("apple", "banana", "orange");
        List<String> strList2 = List.of("grape", "mango");
        System.out.println("String列表匹配结果：" + hasAnyMatch(strList1, strList2)); // false

        // 测试3：自定义对象列表（需确保对象重写equals()和hashCode()）
        List<User> userList1 = List.of(new User(1, "张三"), new User(2, "李四"));
        List<User> userList2 = List.of(new User(2, "李四"), new User(3, "王五"));
        System.out.println("自定义User列表匹配结果：" + hasAnyMatch(userList1, userList2)); // true（李四匹配）

        // 测试4：空列表场景
        List<Integer> emptyList = List.of();
        System.out.println("空列表匹配结果：" + hasAnyMatch(intList1, emptyList)); // false
    }


    /**
     * 自定义对象示例：需重写equals()和hashCode()，确保Set.contains()能正确匹配
     */
    static class User {
        private Integer id;
        private String name;

        public User(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        // 重写equals：以id作为匹配依据（业务可按需调整，如id+name联合匹配）
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return id.equals(user.id);
        }

        // 重写hashCode：与equals逻辑一致（基于id）
        @Override
        public int hashCode() {
            return id.hashCode();
        }
    }
}
